package no.ntnu.idi.deid.postprocessor;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Scanner;

import no.ntnu.idi.deid.config.FilePaths;
import no.ntnu.idi.deid.documentunits.Document;
import no.ntnu.idi.deid.documentunits.Token;
import no.ntnu.idi.deid.documentunits.TokenIterator;
import no.ntnu.idi.deid.preprocessor.Documents;

public class DocumentReConstructer {
	

	private Documents preProcessedDocuments;
	
	private DocumentReConstructer(Documents pre,boolean constructLemmatized, boolean constructDeIdentified){
		preProcessedDocuments = pre;
		constructFiles(constructLemmatized,constructDeIdentified);
	}
	
	public static DocumentReConstructer constructLemmatizedFiles(Documents pre) {
		return new DocumentReConstructer(pre, true, false);
	}
	
	public static DocumentReConstructer constructDeIdentifiedFiles(Documents pre) {
		return new DocumentReConstructer(pre, false, true);
	}
	
	public void constructFiles(boolean constructLemmatized, boolean constructDeIdentified){
		Scanner sc = null;
		for(Document doc: preProcessedDocuments){
			try {
				sc = new Scanner(new File(FilePaths.getWashedFilesFolder()+doc.getName()));
				
				construct(constructLemmatized,constructDeIdentified, sc, doc);
			}
			catch (Exception e) {
				e.printStackTrace();
			}
		}
		
	}
	
	private void construct(boolean constructLemmatized, boolean constructDeIdentified, Scanner sc, Document doc) {
		if(constructLemmatized) {constructLemmatized(sc, doc);}
		if(constructDeIdentified) {constructDeIdentified(sc, doc);}
	}
		
	private void constructLemmatized(Scanner sc, Document doc){
		Writer writer = null;
		try {
			writer = new BufferedWriter(new OutputStreamWriter( new FileOutputStream(FilePaths.getLemmatizedDirectory()+doc.getName()), "utf-8"));
			TokenIterator tokenIterator = new TokenIterator(doc);
			Token tempToken = null;
			ArrayList<Token> writeList = new ArrayList<Token>();
			while(sc.hasNext()){
				String[] line = sc.nextLine().split(" ");
				if(line.length>0){
					if(!(line[0].trim().isEmpty() && line.length==1)){
						createLineList(tokenIterator, tempToken, writeList,
								line);
						for(Token t: writeList){
							if(t.hasStemmedToken()) {
								if(t.isTokenClean() || t.getOrginal().length() < 2) {
									writer.write(t.getStemmedToken()+ " ");
								}
								else{
									String newString = t.getStemmedToken()+ " ";
									if(!Character.isLetterOrDigit(t.getOrginal().charAt(0))) {
										newString = t.getOrginal().charAt(0)+newString;
									}
									if(!Character.isLetterOrDigit(t.getOrginal().charAt(t.getOrginal().length()-1))){
										newString = newString+t.getOrginal().charAt(t.getOrginal().length()-1);
									}
									writer.write(newString+ " ");
								}
							}
							else {
								writer.write(t.getOrginal()+ " ");
							}
							
						}
						writer.write("\n");
					}
					else{
						writer.write("\n");
					}	
				}
				else{
					writer.write("\n");
				}
				writeList.clear();
			}
			writer.close();
		}
		catch (IOException e) {e.printStackTrace();}
	}
		
	private void constructDeIdentified(Scanner sc, Document doc){
		Writer writer = null;
		try {
			writer = new BufferedWriter(new OutputStreamWriter( new FileOutputStream(FilePaths.getDeIdentifiedFilesFolderPath()+doc.getName()), "utf-8"));
			TokenIterator tokenIterator = new TokenIterator(doc);
			Token tempToken = null;
			ArrayList<Token> writeList = new ArrayList<Token>();
			while(sc.hasNext()){
				String[] line = sc.nextLine().split(" ");
				if(line.length>0){
					if(!(line[0].trim().isEmpty() && line.length==1)){
						createLineList(tokenIterator, tempToken, writeList,
								line);
						for(Token t: writeList){
							writer.write(t.getFinalString()+ " ");
						}
						writer.write("\n");
					}
					else{
						writer.write("\n");
					}	
				}
				else{
					writer.write("\n");
				}
				writeList.clear();
			}
			writer.close();
		}
		catch (IOException e) {e.printStackTrace();}
	}

	private void createLineList(Iterator<Token> tokenIterator, Token tempToken,
			ArrayList<Token> writeList, String[] line) {
		do{
			try{
				tempToken = tokenIterator.next();
				writeList.add(tempToken);
			}catch(NoSuchElementException e) {
				e.printStackTrace();
				System.err.print("Please use UTF-8");
			}
				
		}while(!tempToken.getOrginal().contains(line[line.length-1].trim()));
	}
	

}



//			for(Section sec: doc.getSections()){
//				for(Sentence sen: sec.getSentences()){
//					for(Token t: sen.getTokens()){
//						writer.write(t.toString() + " ");
//					}
//					writer.write("\n");
//				} 
//				writer.write("\n");
//			}